package com.romadan.base;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.romadan.core.linearanalys.fet.model14els.ExtrinsicElements;
import com.romadan.core.linearanalys.fet.model14els.IntrinsicElements;
import com.romadan.core.linearanalys.filereader.SParametersReader;
import com.romadan.core.linearanalys.filereader.SParametersReaderImplForMWO;
import com.romadan.core.linearanalys.logic.LParameters;
import com.romadan.core.linearanalys.logic.SParameters;
import com.romadan.core.nonlinearanalys.fet.volterra.ConvertFromSchemaToGraph;
import com.romadan.core.nonlinearanalys.fet.volterra.ModelParameters;
import com.romadan.core.nonlinearanalys.fet.volterra.logic.GraphType;
import com.romadan.core.nonlinearanalys.fet.volterra.logic.NLParameters;
import com.romadan.gui.controller.AbstractController;
import com.romadan.utils.UnitConversions;
import com.romadan.utils.math.Complex;

public class ActionsController {
	private SParametersReader reader;

	public ActionsController() {
		reader = new SParametersReaderImplForMWO();
	}

	public LParameters executeLinearAnalysis(Map<String, String> parameters) {
		LParameters l = new LParameters();

		String strFlp = parameters.get("f_lp");
		String strFhp = parameters.get("f_hp");
		String strFhot = parameters.get("f_hot");

		String pathSlp = parameters.get("s_lp");
		String pathShp = parameters.get("s_hp");
		String pathShot = parameters.get("s_hot");

		double f_lp = UnitConversions.frequencyLinearToCyclic(strFlp, null);
		double f_hp = UnitConversions.frequencyLinearToCyclic(strFhp, null);
		double f_hot = UnitConversions.frequencyLinearToCyclic(strFhot, null);
		File fileSlp = new File(pathSlp);
		File fileShp = new File(pathShp);
		File fileShot = new File(pathShot);

		if (fileShot == null || !fileShot.isFile())
			return null;

		reader.setFileSParameters(fileSlp);
		List<SParameters> s_lp = reader.getSParameters();

		reader.setFileSParameters(fileShp);
		List<SParameters> s_hp = reader.getSParameters();

		ExtrinsicElements extrinsic = new ExtrinsicElements(s_lp, s_hp);
		extrinsic.calculateForOneFrequency(f_lp, f_hp);

		reader.setFileSParameters(fileShot);
		List<SParameters> s_hot = reader.getSParameters();

		IntrinsicElements intrinsic = new IntrinsicElements(s_hot, extrinsic);
		intrinsic.calculateForOneFrequency(f_hot);

		l.setFrequency(f_hot);
		l.setExtElements(extrinsic);
		l.setIntElements(intrinsic);

		l.setVoltageDS(reader.getVoltageDS());
		l.setVoltageGS(reader.getVoltageGS());

		return l;
	}

	public List<LParameters> executeMultimodeLinearAnalysis(
			Map<String, String> parameters) {
		List<LParameters> ll = new ArrayList<LParameters>();

		String pathShot = parameters.get("s_hot");
		File dirShot = new File(pathShot);

		if (!dirShot.isDirectory())
			return null;

		for (File s_hot : dirShot.listFiles()) {
			parameters.put("s_hot", s_hot.getAbsolutePath());
			LParameters l = executeLinearAnalysis(parameters);
			if (l != null)
				ll.add(l);
		}

		return ll;
	}

	public NLParameters executeNonlinearAnalysisForVolterra(
			Map<String, String> parameters) {
		ModelParameters model = null;
		GraphType graph = null;
		List<LParameters> llp = AbstractController.getLinearParameters();
		if (llp != null && llp.size() != 0) {
			LParameters lp = llp.get(0);
			ConvertFromSchemaToGraph converter = new ConvertFromSchemaToGraph(
					lp);
			graph = converter.convert();

			Map<String, Object> data = new HashMap<String, Object>();
			data.put("am1", Double.parseDouble(parameters.get("txtAmplitude1")));
			data.put("am2", Double.parseDouble(parameters.get("txtAmplitude2")));
			data.put("freq1",
					Double.parseDouble(parameters.get("txtFrequency1")));
			data.put("freq2",
					Double.parseDouble(parameters.get("txtFrequency2")));

			data.put("vout12", parseComplex(parameters.get("txtVoltage12")));
			data.put("vout22", parseComplex(parameters.get("txtVoltage22")));
			data.put("vout13", parseComplex(parameters.get("txtVoltage13")));
			data.put("vout23", parseComplex(parameters.get("txtVoltage23")));
			data.put("vout122", parseComplex(parameters.get("txtVoltage122")));

			model = new ModelParameters(graph, data);
			NLParameters nlp = model.getParameters();
			// add first order coefficients
			nlp.setGm1(new Complex(Math.abs(lp.getIntElements().getGm()), 0));
			nlp.setGd1(new Complex(Math.abs(lp.getIntElements().getGds()), 0));
			nlp.setCgs1(new Complex(Math.abs(lp.getIntElements().getCgs()), 0));
			nlp.setCgd1(new Complex(Math.abs(lp.getIntElements().getCgd()), 0));

			return nlp;
		} else {
			System.out.println("Firstly needed perform the linear analysis");
			return null;
		}
	}

	public void setSParameterReader(Class<SParametersReader> classReader) {
		try {
			reader = classReader.newInstance();
		} catch (Exception e) {
			System.out.println("Error:\n" + e.getLocalizedMessage());
		}
	}

	private Complex parseComplex(String str) {
		if (str.contains("j")) {
			String real = str.substring(0, str.indexOf("j") - 1);
			String imag = str.substring(str.indexOf("j") - 1, str.indexOf("j"))
					+ str.substring(str.indexOf("j") + 1);
			real = real.replace(" ", "");
			imag = imag.replace(" ", "");
			return new Complex(new Double(real), new Double(imag));
		} else if (str.length() != 0) {
			return new Complex(new Double(str.replace(" ", "")), 0);
		} else {
			return Complex.ZERO;
		}
	}
}
